В этом документе подробно описывается, как использовать Vivado 2021 и Vitis 2021 для отображения четырех цветных полос на мониторе компьютера через интерфейс HDMI путем настройки аппаратного обеспечения, программного обеспечения и ограничений по выводам. Объяснение будет дополнено предоставленными схемами аппаратного дизайна модулей проекта, изображениями результатов эксперимента и блок-схемой системы.
Модуль сброса процессорной системы
Функция: Этот модуль используется для генерации и управления сигналами сброса системы. Он обеспечивает, что во время запуска и работы системы все модули могут быть сброшены с правильной синхронизацией, предотвращая нестабильность системы.
Модуль AXI Interconnect
Функция: Модуль AXI Interconnect используется для подключения нескольких устройств шины AXI (Advanced eXtensible Interface). Он обеспечивает передачу данных и управляющих сигналов между несколькими ведущими и ведомыми устройствами, гарантируя правильный поток данных между различными модулями.
Модуль прямого доступа к памяти для видео AXI
Функция: Этот модуль выполняет операции прямого доступа к памяти (DMA) между видеоданными и памятью. Он эффективно обрабатывает передачу видеоданных, снижая нагрузку на ЦП и повышая производительность системы.
Модуль контроллера видеосинхронизации
Функция: Модуль контроллера видеосинхронизации отвечает за генерацию сигналов видеосинхронизации, таких как горизонтальная синхронизация, вертикальная синхронизация и тактовый сигнал пикселей. Эти сигналы критически важны для правильного отображения видеоданных на мониторе.
Модуль VDMA
Функция: Модуль VDMA (Video DMA) используется для высокоскоростной передачи данных между видеоданными и системной памятью. Он может считывать видеоданные из памяти в соответствии с сигналами синхронизации, генерируемыми контроллером видеосинхронизации, и передавать их на дисплей.
Блок-схема системы выглядит следующим образом:
Секция PS (Processing System)
ARM Cortex-A9: Это главный процессор системы, отвечающий за выполнение программного обеспечения и управление общей работой системы.
Интерфейсы HP и GP: Эти интерфейсы используются для подключения различных периферийных устройств, обеспечивая передачу данных и управляющих сигналов.
Память DDR: Используется для хранения программ и данных, необходимых для работы системы, обеспечивая высокоскоростное хранение и доступ к данным.
Секция PL (Programmable Logic)
VDMA: Имеет ту же функцию, что и упомянутый ранее модуль VDMA, отвечает за доступ к памяти видеоданных.
Video Timing Controller: Генерирует сигналы видеосинхронизации для обеспечения правильного отображения видеоданных.
AXI-Stream to DVI Transmitter: Этот модуль преобразует видеоданные из формата AXI-Stream в формат DVI (Digital Visual Interface) для передачи на монитор через интерфейс HDMI.
HDMI Display: Используется для отображения конечного видеовыхода.
Упакуйте секцию драйвера HDMI в IP-ядро для последующего прямого импорта.
На основе предыдущего аппаратного дизайна нам необходимо добавить дизайн IP-ядра ZYNQ:
IP-ядро после настройки:
Найдите ядро VDMA и настройте его, как показано на рисунке ниже:
Найдите ядро синхронизации и настройте его, как показано на рисунке ниже:
Найдите ядро видеовыхода и настройте его, как показано на рисунке ниже:
Найдите ядро тактирования и настройте его, как показано на рисунке ниже:
Добавьте пользовательское IP: dvi_transmitter. Это IP-ядро находится в папке ip_repo в каталоге проекта.
После добавления подключите и выведите внешние порты (необходимо вывести только порт TMDS). Подключите pclk_x5 к clkout2 тактового выхода из предыдущего шага.
Выполните соединения, затем нажмите «Run Connection Automation». Модули и их интерфейсы, которые будут автоматически подключены, перечислены ниже. Установите флажок «All Automation», а затем нажмите кнопку «OK». Система автоматически сгенерирует два модуля AXI Interconnect (axi_mem_intercon и ps7_0_axi_periph). Кроме того, система также автоматически сгенерирует один модуль сброса (rst_ps7_0_150M) для сброса периферийных устройств на шине.
После изменения блочного дизайна сохраните его, затем перегенерируйте Output Products и «Create HDL Wrapper». Далее нам нужно изменить файл ограничений, чтобы назначить выводы для интерфейса HDMI в соответствии со схемой.
Сохраните файл ограничений, затем перейдите к последующим шагам для перегенерации файла BIT.
Щелкните правой кнопкой мыши по созданному проекту платформы, выберите «Update Hardware Specification», укажите путь к файлу .xsa. Появится следующее диалоговое окно; нажмите OK, что означает успешное обновление. Хорошая практика: после обновления снова щелкните правой кнопкой мыши по проекту платформы и выберите «Build».
Напишите код в программном проекте. В программном коде определите данные для четырех цветных полос (красной, зеленой, синей, белой). Реализуйте генерацию и передачу этих данных.
Сохраните данные этих цветных полос в памяти DDR и передайте их на дисплей через модуль VDMA.
x
//VDMA device ID//VTC device ID
XAxiVdma vdma;DisplayCtrl dispCtrl;VideoMode vd_mode;
unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x1000000);
int main(void){ xil_printf("HDMI Display 1920*1080 \r\n");
//set video parameters, resolution: 1920*1080 vd_mode = VMODE_1920x1080;
//configure VDMA run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height, frame_buffer_addr,0, 0,ONLY_READ);
//initialize Display controller DisplayInitialize(&dispCtrl, DISP_VTC_ID); //set VideoMode DisplaySetMode(&dispCtrl, &vd_mode); DisplayStart(&dispCtrl);
int y = 0; int x = 0; for(y = 0; y < vd_mode.height; y++) { for(x = 0; x < vd_mode.width; x++) if (x >= 0 && x < (vd_mode.width / 4) * 1) { // white *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+0)=0xff; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+1)=0xff; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+2)=0xff; } else if (x >= (vd_mode.width/4)*1 && x < (vd_mode.width/4)*2) { // red *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+0)=0x00; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+1)=0x00; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+2)=0xff;
} else if (x >= (vd_mode.width/4)*2 && x < (vd_mode.width/4)*3) { // green *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+0)=0x00; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+1)=0xff; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+2)=0x00; } else { // blue *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+0)=0xff; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+1)=0x00; *((u8 *)frame_buffer_addr+y*vd_mode.width*3+3*x+2)=0x00; } }
Xil_DCacheFlush(); //flush Cache,update data to DDR while(1) {
} return 0; }
После успешной компиляции проекта подключите JTAG отладочной платы к компьютеру с помощью кабеля USB Type-C. Используйте другой кабель USB Type-C для подключения PS UART платы к компьютеру. Используйте кабель HDMI для подключения выходного порта HDMI платы к входному порту HDMI монитора компьютера.
На компьютере откройте инструмент серийной отладки MobaXterm и установите соединение с PS UART отладочной платы.
Войдите в режим отладки в Vitis: в разделе «Debug As» выберите первый вариант. Запуск на полной скорости позволит вам видеть отладочную информацию через последовательный порт.
Результаты отладки следующие:
Результаты выполнения следующие: